'''
Created on 2010-2-16

@author: summit
'''
import sys
from Queue import Queue
from Array import Array
from Iterator import Iterator
from Visitor import Visitor
from Exception import *

class QueueAsArray(Queue):
    '''
    Queue implemented using an array.
    '''


    def __init__(self, size=0):
        '''
        Constructs a queue of the given size.
        '''
        super(QueueAsArray, self)
        self._array = Array(size)
        self._head = 0
        self._tail = size - 1
    
    def purge(self):
        '''
        Purges this queue
        '''
        while self._count > 0:
            self._array[self._head] = None
            self._head = self._head + 1
            if self._head == len(self._array):
                self._head = 0
            self._count -= 1
    
    def getHead(self):
        '''
        Returns the object at the head of this queue.
        '''
        if self._count == 0:
            raise ContainerEmpty
        return self._array[self._head]
    
    def enqueue(self, obj):
        '''
        Enqueues the given object to the tail of this queue.
        '''
        if self._count == len(self._array):
            raise ContainerFull
        self._tail = self._tail + 1
        if self._tail == len(self._array):
            self._tail = 0
        self._array[self._tail] = obj
        self._count += 1
    
    def dequeue(self):
        '''
        Dequeues the object at the head of this queue.
        '''
        if self._count == 0:
            raise ContainerEmpty
        result = self._array[self._head]
        self._array[self._head] = None
        self._head = self._head + 1
        if self._head == len(self._array):
            self._head = 0
        self._count -= 1
        return result
    
    def getIsFull(self):
        '''
        Returns true of this queue is full.
        '''
        return self._count == len(self._array)
    
    def accept(self, visitor):
        '''
        Makes the given visitor visit all the objects in this queue.
        '''
        assert isinstance(visitor, Visitor)
        pos = self._head
        for i in xrange(self._count):
            visitor.visit(self._array[pos])
            if visitor.isDone:
                return
            pos = pos+1
            if pos == len(self._array):
                pos=0
    
    class Iterator(Iterator):
        '''
        Enumerates the elements of a QueueAsArray.
        '''
        
        def __init__(self, queue):
            '''
            Constructs an iterator for the given queue.
            '''
            super(QueueAsArray.Iterator).__init__(queue)
            self._position = -1
        
        def next(self):
            '''
             Returns the next element.
            '''
            self._position = self._position + 1
            if self._position == self._container.getCount():
                self._position = -1
                raise StopIteration
            return self._container._array[
                                (self._container._head+self._position)
                                %len(self._container._array)]
    def __iter__(self):
        '''
        Returns an iterator for this queue.
        '''
        return self.Iterator(self)
    
    def _compareTo(self, obj):
        '''
        Comparse this queue with the given queue.
        '''
        assert isinstance(self, obj.__class__)
        raise NotImplementedError
    
    def main(*argv):
        "QueueAsArray test program."
        print QueueAsArray.main.__doc__
        queue1 = QueueAsArray(5)
        Queue.test(queue1)
        return 0
    main = staticmethod(main)

if __name__ == "__main__":
    sys.exit(QueueAsArray.main(*sys.argv))